/*
 * Filename:  ValidateImageGenerator.java
 * Copyright:  Raisetop Technologies Co., Ltd. Copyright YYYY-YYYY,  All rights reserved
 * Description:  <description>
 * Author:  donghu
 * Edit-time:  2016-6-7
 * Tracking odd Numbers:  <odd Numbers>
 * Modify the odd Numbers:  <odd Numbers>
 * Modify content:  <modify content>
 */
package com.gutetec.cms.usmc.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;


/**
 * <Generate verification code>
 * <Function details>
 * @author  donghu
 * @version  [Version, 2016-6-7]
 * @see  [Classs/Method]
 * @since  [Product/Model Version]
 */
public class ValidateImageGenerator
{
    // create Random object
    static Random random = new Random();
    
    /**
     * <create random key of string>
     * <Detailed description of function>
     * @param num
     * @return
     * @see [class/function]
     */
    public static String randomStr(int num)
    {
        // init key
        String[] str = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
            "a", "b", "c", "d", "e", "f", "g", "h",
            "k", "m", "n", "p", "q", "r", "s", "t",
            "A", "B", "C", "D", "E", "F", "G", "H",
            "K", "M", "N", "P", "Q", "R", "S", "T"};
        int number = str.length;
        
        // get random text
        String text = "";
        
        // create random the number of num
        for (int i = 0; i < num; i++)
        {
            text += str[random.nextInt(number)];
        }
        return text;
    }
    
    /**
     * <create random key of color>
     * <Detailed description of function>
     * @return
     * @see [class/function]
     */
    private static Color getRandColor()
    {
        Random random = new Random();
        Color color[] = new Color[10];
        color[0] = new Color(32, 158, 25);
        color[1] = new Color(218, 42, 19);
        color[2] = new Color(31, 75, 208);
        color[3] = new Color(0, 102, 182);
        color[4] = new Color(171, 0, 85);
        return color[random.nextInt(5)];
    }
    
    /**
     * <create random key of font>
     * <Detailed description of function>
     * @return
     * @see [class/function]
     */
    private static Font getFont()
    {
        Random random = new Random();
        Font font[] = new Font[5];
        font[0] = new Font("Candara", Font.PLAIN, 22);
        font[1] = new Font("Arial Black", Font.PLAIN, 22);
        font[2] = new Font("Verdana", Font.PLAIN, 22);
        font[3] = new Font("Constantia", Font.PLAIN, 22);
        font[4] = new Font("Tahoma", Font.PLAIN, 22);
        return font[random.nextInt(5)];
    }
    
    /**
     * <create verification code image>
     * <Detailed description of function>
     * @param strLen
     * @param out
     * @param width
     * @param height
     * @throws IOException
     * @see [class/function]
     */
    public static void renderVerificationCode(String randomStr, OutputStream out, int width, int height)
        throws IOException
    {
        // create image in memory
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
        
        // get context of Graphics
        Graphics2D g = (Graphics2D)bi.getGraphics();
        
        // border
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);
        g.setFont(getFont());
        g.setColor(Color.BLACK);
        
        // Painting authentication code, each authentication code in a different level of location
        String str1[] = new String[randomStr.length()];
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str1.length; i++)
        {
            str1[i] = randomStr.substring(i, i + 1);
            int w = 0;
            int x = (i + 1) % 3;
            
            // Random generation verification code character level offset
            if (x == random.nextInt(4))
            {
                w = 25 - random.nextInt(4);
            }
            else
            {
                w = 25 + random.nextInt(4);
            }
            
            // Random generation color
            g.setColor(getRandColor());
            g.drawString(str1[i], 15 * i + 1, w);
            sb.append(str1[i]);
        }
        
        // 生成的验证码放到内存中
        UsmcUtil.generateCodeMap.put(sb.toString().toLowerCase(), sb.toString());
        
        // Randomly generated interference points with different color
        for (int i = 0; i < 50; i++)
        {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            Color color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
            
            // set different color
            g.setColor(color);
            g.drawOval(x, y, 0, 0);
        }
        
        // generated interference lines
        for (int i = 0; i < 5; i++)
        {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            Color color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
            
            // set different color
            g.setColor(color);
            g.drawLine(x, y, x1, y1);
        }
        
        // generation image
        g.dispose();
        
        // output image
        ImageIO.write(bi, "jpg", out);
    }
}
